//@ts-nocheck
import dayjs from "dayjs";
import React, { useState, useRef, useCallback } from "react";
import {
  Button,
  View,
  StyleSheet,
  Text,
  TouchableOpacity,
  FlatList,
  Image,
} from "react-native";
import DateTimePickerModal from "react-native-modal-datetime-picker";
import { Picker } from "@react-native-picker/picker";
import Modal from "react-native-modal";
import {
  WritableWithResponse,
  determineCurrentDevice,
  getStorageData,
  rmStorageData,
  setStorageData,
} from "utils";
import toast from "utils/toast";
import { useAppSelector } from "app/store";
import Spinner from "react-native-loading-spinner-overlay";
import { manager } from "utils/bleManage";
import iconv from "@vscode/iconv-lite-umd";
import { useFocusEffect } from "@react-navigation/native";
import translate from "utils/translate";
const Buffer = require("@craftzdog/react-native-buffer").Buffer;
type Search = {
  endTime: string;
  startTime: string;
  goodsName: string;
  deviceName: string;
};
const renderGoodsItem = ({ item }) => (
  <View
    style={{
      flexDirection: "row",
      justifyContent: "space-between",
      padding: 10,
      borderBottomColor: "#ccc",
      borderBottomWidth: 1,
    }}
  >
    <Text>{item.goodsName}</Text>
    <View>
      <Text style={{ marginBottom: 5 }}>{`${translate("main.weight")}:${
        item.weightCount
      }`}</Text>
      <Text>{`${translate("main.quantity")}:${item.count}`}</Text>
    </View>
    <View>
      <Text style={{ marginBottom: 5 }}>{`${translate("main.amount")}:${
        item.weightTotal ?? 0
      }`}</Text>
      <Text>{`${translate("main.amount")}:${item.total}`}</Text>
    </View>
  </View>
);
const renderRecordItem = ({ item }) => (
  <View
    style={{ padding: 10, borderBottomColor: "#ccc", borderBottomWidth: 1 }}
  >
    <View style={{ flexDirection: "row", justifyContent: "space-between" }}>
      <Text>{item.goodsName}</Text>
      <Text>
        {translate("main.quantityWei") +
          ":" +
          (item.count + "").replace(/^0+(?=\d)/, "")}
      </Text>
    </View>
    <View
      style={{
        flexDirection: "row",
        justifyContent: "space-between",
        marginTop: 5,
        marginBottom: 5,
      }}
    >
      <Text>{translate("class.price") + ":" + item.price}</Text>
      <Text>{translate("main.salePrice") + ":" + item.price}</Text>
      <Text>{translate("main.amount") + ":" + item.amount ?? 0}</Text>
    </View>
    <Text style={{ alignSelf: "flex-end" }}>{item.createTime}</Text>
  </View>
);
const Home = () => {
  const connectedDevice = useAppSelector((state) => {
    return state.app.connectedDevice;
  });
  const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
  const [ModalVisible, setModalVisible] = useState(false);
  const [DelRecordModalVisible, setDelRecordModalVisible] = useState(false);
  const [loading, setLoading] = useState(false);
  const [searchForm, setsearchForm] = useState<Search>({
    goodsName: "",
    startTime: dayjs().subtract(1, "month").format("YYYY-MM-DD HH:mm:ss"),
    endTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
    deviceName: "",
  });
  useFocusEffect(
    useCallback(() => {
      initialize();
    }, [searchForm])
  );
  const [options, setOptions] = useState<string[]>([]);
  const [goodsOptions, setGoodsOptions] = useState<string[]>([]);
  const [recordNums, setRecordNums] = useState(0);
  const [totalprice, setTotalprice] = useState(0);
  const [List, setList] = useState([]);
  const saleList = useRef([]);
  const isStartTime = useRef(true);
  const onCancel = () => {
    setDatePickerVisibility(false);
  };
  function duplicate(key, List) {
    const uniqueArray = List.reduce((accumulator, current) => {
      // 检查累加器中是否已存在相同值的项
      if (!accumulator.some((item) => item[key] == current[key])) {
        // 如果不存在，则添加到累加器中
        accumulator.push(current);
      }

      return accumulator;
    }, []);
    return uniqueArray;
  }
  const initialize = () => {
    getStorageData("saleList").then((value) => {
      const List = value ? JSON.parse(value) : [];
      saleList.current = List;
      const startValue = dayjs(searchForm.startTime).valueOf();
      const endtValue = dayjs(searchForm.endTime).valueOf();
      if (searchForm.goodsName === translate("scale.CommoditySummary")) {
        let arr;
        if (searchForm.deviceName) {
          arr = saleList.current.find(
            (item) => item.deviceId == searchForm.deviceName
          ).sale;
        } else {
          arr = saleList.current.map((item) => item.sale).flat();
        }
        const filterListbyTime = arr.filter((item) => {
          const id = dayjs(item.createTime).valueOf();
          return id > startValue && id < endtValue;
        });
        const groupedData = filterListbyTime.reduce((acc, item) => {
          const existingCategory = acc.find(
            (category) => category[0].goodsName === item.goodsName
          );
          if (existingCategory) {
            existingCategory.push(item);
          } else {
            acc.push([item]);
          }
          return acc;
        }, []);
        const sum = (key, list) => {
          return list.reduce((pre, cur) => {
            return pre + Number(cur[key]);
          }, 0);
        };
        const adata = groupedData.map((item) => {
          return {
            weightTotal: sum(
              "amount",
              item.filter((item) => !item.isNums)
            ).toFixed(2),
            goodsName: item[0].goodsName,
            weightCount: sum(
              "count",
              item.filter((item) => !item.isNums)
            ).toFixed(3),
            count: sum(
              "count",
              item.filter((item) => item.isNums)
            ),
            total: sum(
              "amount",
              item.filter((item) => item.isNums)
            ).toFixed(2),
          };
        });
        setList(adata);
        setTotalprice(
          (sum("total", adata) + sum("weightTotal", adata)).toFixed(2)
        );
      } else {
        const arrs = (
          searchForm.deviceName
            ? List.filter((item) => item.deviceId === searchForm.deviceName)
            : List
        )
          .map((item) => item.sale)
          .flat()
          .filter((item) => {
            return searchForm.goodsName
              ? item.goodsName == searchForm.goodsName
              : item;
          });
        const totalprice = arrs.reduce((pre, cur) => {
          return pre + Number(cur.amount);
        }, 0);
        setOptions(
          List.map((item) => ({ name: item.name, value: item.deviceId }))
        );
        setRecordNums(arrs.length ?? 0);
        setTotalprice(totalprice);
        const filterListbyTime = arrs.filter((item) => {
          const id = dayjs(item.createTime).valueOf();
          return id > startValue && id < endtValue;
        });
        setList(filterListbyTime);
      }
    });
  };
  const salemoney = (data, needLength = true) => {
    const arrs = data.map((item) => item.sale).flat();
    const totalprice = arrs.reduce((pre, cur) => {
      return pre + Number(cur.amount);
    }, 0);
    setTotalprice(totalprice);
    if (needLength) {
      setRecordNums(arrs.length);
    }
  };
  const handleConfirm = (date: Date) => {
    setsearchForm((pre) => {
      return {
        ...pre,
        [isStartTime.current ? "startTime" : "endTime"]: dayjs(date).format(
          "YYYY-MM-DD HH:mm:ss"
        ),
      };
    });
    setDatePickerVisibility(false);
  };
  const delStorage = () => {
    rmStorageData("saleList").then(() => {
      initialize();
      toast(translate("main.success"));
      setRecordNums(0);
    });
  };
  const delrecord = async () => {
    if (connectedDevice) {
      setLoading(true);
      const services = await manager
        .discoverAllServicesAndCharacteristicsForDevice(connectedDevice)
        .then((device) => {
          return device.services();
        })
        .catch(() => {
          toast(translate("main.error"));
        });
      if (services) {
        const item = determineCurrentDevice(services);
        if (item) {
          const characteristicsList = await item.characteristics();
          for (let current of characteristicsList) {
            if (current.isWritableWithResponse && current.isNotifiable) {
              try {
                await WritableWithResponse(current, "AA");
                await WritableWithResponse(current, "18");
                await WritableWithResponse(current, "0F");
                toast(translate("main.success"));
                setLoading(false);
              } catch {
                setLoading(false);
                // toast("发送指令失败");
                toast(translate("main.error"));
              }
              return;
            }
          }
        } else {
          setLoading(false);
          toast(translate("main.error"));
        }
      }
    } else {
      toast(translate("main.connectTip"));
    }
  };
  const onSync = () => {
    if (connectedDevice) {
      handleSync();
    } else {
      toast(translate("main.connectTip"));
    }
  };
  function gbkHexToString(hexString: string) {
    // 将十六进制字符串转换为 Buffer
    const buffer = Buffer.from(hexString, "hex");
    // 将 Buffer 转换为字符串
    const result = iconv.decode(buffer, "gbk");
    return result;
  }
  const handleSync = async () => {
    setLoading(true);
    const services = await manager
      .discoverAllServicesAndCharacteristicsForDevice(connectedDevice as string)
      .then((device) => {
        return device.services();
      })
      .catch(() => {
        toast(translate("main.error"));
      });
    if (services) {
      const item = determineCurrentDevice(services);
      if (item) {
        const characteristicsList = await item.characteristics();
        for (let current of characteristicsList) {
          if (current.isWritableWithResponse && current.isNotifiable) {
            try {
              await WritableWithResponse(current, "AA");
              await WritableWithResponse(current, "08");
              let List = [];
              let str = "";
              const download = /0d0a/i;
              const Subscription = current.monitor((err, characteristic) => {
                if (err && err.reason) {
                  toast(err.reason, 5 * 1000);
                  return Subscription.remove();
                }
                if (characteristic?.value) {
                  const resData = Buffer.from(
                    JSON.stringify(characteristic.value),
                    "base64"
                  ).toString("hex");
                  if (resData == "0f") {
                    const keyList = [
                      "createTime",
                      "goodsName",
                      "count",
                      "price",
                      "amount",
                    ];
                    List = List.map((it) => {
                      const data = it
                        .replace(/\s/g, "")
                        .replace(/0d0a/i, "")
                        .split(/0c/i);
                      const itemData = Object.fromEntries(
                        data.map((item, index) => {
                          return [
                            keyList[index],
                            index === 0
                              ? gbkHexToString(item).replaceAll(".", "-")
                              : gbkHexToString(item).replace(/\s/g, ""),
                          ];
                        })
                      );
                      return {
                        ...itemData,
                        isNums: !/\d*\.\d+/.test(itemData.count),
                      };
                    });
                    getStorageData("saleList").then(async (value) => {
                      const dataList = value ? JSON.parse(value) : [];
                      const index = dataList.findIndex(
                        (item) => item.deviceId == connectedDevice
                      );
                      if (index !== -1) {
                        List.unshift(...dataList[index].sale);
                        const uniqueArray = List.reduce(
                          (accumulator, current) => {
                            // 检查累加器中是否已存在相同值的项
                            if (
                              !accumulator.some(
                                (item) =>
                                  dayjs(item["createTime"]).valueOf() ===
                                  dayjs(current["createTime"]).valueOf()
                              )
                            ) {
                              // 如果不存在，则添加到累加器中
                              accumulator.push(current);
                            }

                            return accumulator;
                          },
                          []
                        );
                        dataList.splice(index, 1, {
                          ...dataList[index],
                          sale: uniqueArray,
                        });
                      } else {
                        const value = await getStorageData("bleList");
                        const name = JSON.parse(value).find(
                          (item) => item.uuid == connectedDevice
                        ).name;
                        dataList.unshift({
                          sale: List,
                          deviceId: connectedDevice,
                          name,
                        });
                      }
                      await setStorageData(
                        "saleList",
                        JSON.stringify(dataList)
                      );
                      toast(translate("main.success"));
                      setsearchForm((pre) => {
                        return {
                          ...pre,
                          endTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
                        };
                      });
                      // initialize();
                      setLoading(false);
                    });
                    Subscription.remove();
                  } else if (download.test(resData)) {
                    List.unshift(str + resData);
                    str = "";
                    current.writeWithResponse(
                      Buffer.from("0D", "hex").toString("base64")
                    );
                  } else {
                    str += resData;
                  }
                }
              });
              current.writeWithResponse(
                Buffer.from("0D", "hex").toString("base64")
              );
            } catch {
              setLoading(false);
              toast(translate("main.error"));
            }
            return;
          }
        }
      } else {
        setLoading(false);
        toast(translate("main.error"));
      }
    }
  };
  return (
    <View style={styles.container}>
      <Spinner
        visible={loading}
        textContent={translate("main.loading") + "..."}
        textStyle={{
          color: "rgba(10, 89, 247, .8)",
        }}
        color="rgba(10, 89, 247, .8)"
        cancelable
      />
      <DateTimePickerModal
        onConfirm={handleConfirm}
        onCancel={onCancel}
        isVisible={isDatePickerVisible}
        minimumDate={new Date(2010, 0, 1)}
        is24Hour
        mode="datetime"
      ></DateTimePickerModal>
      <View
        style={{
          width: "100%",
          borderBottomColor: "#ccc",
          borderBottomWidth: 1,
          padding: 10,
        }}
      >
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
          }}
        >
          <View style={{ flex: 1 }}>
            <Text>{translate("main.StartTime")}</Text>
          </View>

          <TouchableOpacity
            style={{
              flexDirection: "row",
              alignItems: "center",
              justifyContent: "space-between",
              flex: 3,
            }}
            onPress={() => {
              setDatePickerVisibility(true);
              isStartTime.current = true;
            }}
          >
            <Text style={{ marginLeft: 10 }}>{searchForm.startTime}</Text>
            <Image
              style={styles.drop}
              source={require("assets/images/drop.png")}
            ></Image>
          </TouchableOpacity>
        </View>
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
          }}
        >
          <View style={{ flex: 1 }}>
            <Text style={{ paddingTop: 20 }}>{translate("main.endTime")}</Text>
          </View>
          <TouchableOpacity
            style={{
              paddingTop: 20,
              flexDirection: "row",
              alignItems: "center",
              flex: 3,
              justifyContent: "space-between",
            }}
            onPress={() => {
              setDatePickerVisibility(true);
              isStartTime.current = false;
            }}
          >
            <Text style={{ marginLeft: 10 }}>{searchForm.endTime}</Text>
            <Image
              style={styles.drop}
              source={require("assets/images/drop.png")}
            ></Image>
          </TouchableOpacity>
        </View>
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
          }}
        >
          <View style={{ flex: 1 }}>
            <Text>{translate("scale.DeviceName")}</Text>
          </View>
          <View
            style={{
              flex: 3,
            }}
          >
            <Picker
              mode="dialog"
              selectedValue={searchForm.deviceName}
              onValueChange={(itemValue) => {
                const arrs = duplicate(
                  "goodsName",
                  !itemValue
                    ? saleList.current.map((item) => item.sale).flat()
                    : saleList.current.find(
                        (item) => item.deviceId == itemValue
                      ).sale
                ).map((it) => {
                  if (it.goodsName.includes("或1")) {
                    it.goodsName = it.goodsName.replace(/或1/, "火龙果");
                    it.goodsName = it.goodsName.replace(/或1/, "火龙");
                  } else if (it.goodsName == "遣=热") {
                    it.goodsName = it.goodsName.replace(/遣=热/, "前腿肉");
                  }
                  return it.goodsName;
                });
                setGoodsOptions(itemValue ? arrs : []);
                const itemsData = !itemValue
                  ? saleList.current
                  : saleList.current.find((item) => item.deviceId == itemValue);
                setList(itemsData);
                salemoney(itemValue ? [itemsData] : itemsData, false);
                // setsearchForm((pre) => {
                //   return {
                //     ...pre,
                //     deviceName: itemValue,
                //   };
                // });
                setsearchForm((pre) => {
                  const { deviceName, goodsName, ...rest } = pre;
                  return {
                    ...rest,
                    deviceName: itemValue,
                    goodsName: "",
                  };
                });
              }}
            >
              <Picker.Item label={translate("scale.FullRecord")}></Picker.Item>
              {options.map((item) => {
                return (
                  <Picker.Item
                    key={item.value}
                    label={item.name}
                    value={item.value}
                  ></Picker.Item>
                );
              })}
            </Picker>
          </View>
        </View>
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
          }}
        >
          <View style={{ flex: 1 }}>
            <Text>{translate("class.goodsName")}</Text>
          </View>
          <View
            style={{
              flex: 3,
            }}
          >
            <Picker
              mode="dialog"
              style={{
                flex: 3,
              }}
              selectedValue={searchForm.goodsName}
              onValueChange={(itemValue) => {
                setsearchForm((pre) => {
                  return {
                    ...pre,
                    goodsName: itemValue,
                  };
                });
              }}
            >
              <Picker.Item label={translate("scale.FullRecord")}></Picker.Item>
              <Picker.Item
                label={translate("scale.CommoditySummary")}
                value={translate("scale.CommoditySummary")}
              ></Picker.Item>
              {goodsOptions.map((item) => {
                return (
                  <Picker.Item
                    key={item}
                    label={item}
                    value={item}
                  ></Picker.Item>
                );
              })}
            </Picker>
          </View>
        </View>
      </View>
      <View
        style={{
          flexDirection: "row",
          justifyContent: "space-between",
          padding: 15,
          borderBottomColor: "#ccc",
          borderBottomWidth: 1,
        }}
      >
        <Text>
          {translate("sale.CumulativeSales")}:
          {typeof totalprice === "string" ? totalprice : totalprice.toFixed(2)}
        </Text>
        <Text>
          {translate("sale.MemoryCapacity")}:{recordNums}
        </Text>
      </View>
      <FlatList
        data={List}
        renderItem={
          searchForm.goodsName === translate("scale.CommoditySummary")
            ? renderGoodsItem
            : renderRecordItem
        }
        style={{
          flex: 1,
        }}
        keyExtractor={(_, index) => index + ""}
      />
      <TouchableOpacity
        style={{
          ...styles.button,
          borderRadius: 10,
          marginBottom: 10,
        }}
        onPress={onSync}
      >
        <Text
          style={{
            textAlign: "center",
            color: "#fff",
          }}
        >
          {translate("sale.Synchronous")}
        </Text>
      </TouchableOpacity>
      <View
        style={{
          flexDirection: "row",
        }}
      >
        <TouchableOpacity
          onPress={delrecord}
          style={{ ...styles.button, backgroundColor: "#ff0000" }}
        >
          <Text
            style={{
              textAlign: "center",
              color: "#fff",
            }}
          >
            {translate("manage.clearDeviceRecord")}
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={delStorage}
          style={{ ...styles.button, backgroundColor: "#d93349" }}
        >
          <Text
            style={{
              textAlign: "center",
              color: "#fff",
            }}
          >
            {translate("manage.clearRecord")}
          </Text>
        </TouchableOpacity>
      </View>
      <Modal
        isVisible={DelRecordModalVisible}
        style={{
          alignItems: "center",
        }}
      >
        <View
          style={{
            width: 270,
            height: 150,
            backgroundColor: "#fff",
            borderRadius: 16,
            alignItems: "center",
            justifyContent: "space-evenly",
          }}
        >
          <Text>{translate("main.tip")}</Text>
          <Text>{translate("main.sure")}</Text>
          <View
            style={{
              flexDirection: "row",
              width: "50%",
              justifyContent: "space-around",
            }}
          >
            <Button
              title={translate("main.Cancel")}
              onPress={() => {
                setDelRecordModalVisible(false);
              }}
            />
            <Button
              title={translate("main.Submit")}
              color={"#E6A23C"}
              onPress={delrecord}
            />
          </View>
        </View>
      </Modal>
      <Modal
        isVisible={ModalVisible}
        style={{
          alignItems: "center",
        }}
      >
        <View
          style={{
            width: 270,
            height: 150,
            backgroundColor: "#fff",
            borderRadius: 16,
            alignItems: "center",
            justifyContent: "space-evenly",
          }}
        >
          <Text>{translate("main.tip")}</Text>
          <Text>{translate("main.sure")}</Text>
          <View
            style={{
              flexDirection: "row",
              width: "50%",
              justifyContent: "space-around",
            }}
          >
            <Button
              title={translate("main.Cancel")}
              onPress={() => {
                setModalVisible(false);
              }}
            />
            <Button
              title={translate("main.Submit")}
              color={"#E6A23C"}
              onPress={delStorage}
            />
          </View>
        </View>
      </Modal>
    </View>
  );
};

export default Home;
const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: "#fff" },
  button: {
    backgroundColor: "#0A59F7",
    width: "50%",
    height: 50,
    // borderRadius: 16,
    alignItems: "center",
    justifyContent: "center",
    alignSelf: "center",
  },
  drop: {
    width: 14,
    height: 14,
    marginRight: 18,
  },
});
